import re
from typing import List, Dict, Any
from sqlalchemy.orm import Session
from .models import ResourceDetails, RelationshipDefinition, ResourceEntitiesMap, ResourceCategory
from .nlp_processor import NLPProcessor
from .dependency_analyzer import DependencyAnalyzer
from langchain.docstore.document import Document

class QueryProcessor:
    def __init__(self, db: Session):
        self.db = db
        self.nlp_processor = NLPProcessor(db)
        self.dependency_analyzer = DependencyAnalyzer(db)
    
    def process_query(self, query: str, graph_data: Dict[str, Any], llm_wrapper) -> Dict[str, Any]:
        """处理用户查询并返回结果，增强对上下游依赖查询的处理"""
        try:
            # 构建上下文文档
            context_docs = self.build_context_for_qa(query)
            
            # 如果没有找到相关上下文，返回默认响应
            if not context_docs:
                return {
                    'query': query,
                    'answer': "抱歉，我没有找到与您的查询相关的信息。",
                    'context': []
                }
            
            # 将上下文文档转换为文本
            context_text = "\n".join(context_docs)
            
            # 构造提示词
            prompt = f"""
            基于以下上下文信息，回答用户的问题。
            
            上下文信息：
            {context_text}
            
            用户问题：{query}
            
            请提供一个准确、简洁的回答：
            """
            
            # 使用LLM生成回答
            answer = llm_wrapper.generate_text(prompt)
            
            # 返回结果
            return {
                'query': query,
                'answer': answer,
                'context': context_docs
            }
        except Exception as e:
            # 如果处理过程中出现错误，返回错误信息
            return {
                'query': query,
                'answer': f"处理查询时发生错误: {str(e)}",
                'context': []
            }
    
    def build_context_for_qa(self, query: str) -> List[str]:
        """为问答系统构建上下文文档，增强对上下游依赖查询的处理"""
        print(f"开始处理查询: {query}")
        
        # 1. 检查是否是资源ID查询
        resource_id_pattern = r"资源ID[是为:]?\s*(\d+)\s*的资源详情"
        resource_id_match = re.search(resource_id_pattern, query)
        if resource_id_match:
            print("检测到资源ID查询")
            resource_id = resource_id_match.group(1)
            return self._build_resource_by_id_context(resource_id)
        
        # 2. 检查是否是包含关系查询
        if "包含关系" in query or ("包含" in query and "关系" in query):
            print("检测到包含关系查询")
            return self._build_containment_context()
        
        # 3. 检查是否是上下游依赖查询
        if "上游" in query or "下游" in query or "依赖" in query:
            print("检测到上下游依赖查询")
            return self._build_dependency_context(query)
        
        # 4. 使用NLP处理器的实体提取方法
        entities = self.nlp_processor.extract_entities_from_query(query)
        print(f"从查询'{query}'中提取到实体: {entities}")
        
        all_relevant_resources = []
        
        # 5. 对每个实体进行精确搜索
        for entity in entities:
            resources = self.nlp_processor.search_resources_by_name(entity)
            all_relevant_resources.extend(resources)
            if resources:
                print(f"通过精确搜索找到 {len(resources)} 个资源: {entity}")
        
        # 6. 如果没有找到精确匹配，使用关键词搜索
        if not all_relevant_resources:
            keywords = query.split()
            for keyword in keywords:
                # 跳过常见的停用词
                stop_words = ['什么', '如何', '为什么', '哪个', '哪里', '有没有', '是否', '关系', '有', '和', '与', '及', '以及', '或者', '还是', '上游', '下游', '依赖']
                if keyword not in stop_words:
                    resources = self.nlp_processor.search_resources_by_keyword(keyword)
                    all_relevant_resources.extend(resources)
                    if resources:
                        print(f"通过关键词搜索找到 {len(resources)} 个资源: {keyword}")
        
        # 7. 构建上下文文档
        context_docs = []
        for resource in all_relevant_resources:
            # 获取资源本身的信息
            resource_text = f"资源名称: {resource['name']}\n描述: {resource['description']}\n"
            context_docs.append(resource_text)
            
            # 获取与该资源相关的资源
            related_resources = self.nlp_processor.find_related_resources(resource['id'], depth=1)
            
            for related in related_resources:
                # 获取相关资源的详细信息
                related_detail = self.db.query(ResourceDetails).filter_by(id=related['id']).first()
                if related_detail:
                    related_text = f"资源名称: {related_detail.details_name}\n描述: {related_detail.description}\n与{resource['name']}的关系: {related['relationship']}\n"
                    context_docs.append(related_text)
        
        # 8. 特殊处理关系查询
        if "关系" in query or "关联" in query:
            # 提取查询中的两个实体
            entities = self.nlp_processor.extract_entities_from_query(query)
            if len(entities) >= 2:
                # 查找两个实体之间的关系
                relationships = self.nlp_processor.find_relationship_between_resources(entities[0], entities[1])
                if relationships:
                    relationship_text = f"实体关系信息:\n"
                    for rel in relationships:
                        relationship_text += f"{rel['from']} --({rel['relationship']})--> {rel['to']}\n"
                    
                    context_docs.append(relationship_text)
        
        print(f"最终构建了 {len(context_docs)} 个上下文文档")
        return context_docs
    
    def _build_dependency_context(self, query: str) -> List[str]:
        """构建上下游依赖查询的上下文"""
        # 提取查询中的实体
        entities = self.nlp_processor.extract_entities_from_query(query)
        
        if not entities:
            return []
        
        # 获取第一个实体的详细信息
        entity_name = entities[0]
        resource = self.db.query(ResourceDetails).filter(ResourceDetails.details_name == entity_name).first()
        
        if not resource:
            return []
        
        context_docs = []
        
        # 判断查询类型
        if "上游" in query and "下游" in query:
            # 获取所有依赖
            all_deps = self.dependency_analyzer.find_all_dependencies(resource.id)
            if all_deps:
                context_text = f"{entity_name}的所有依赖关系:\n"
                for dep in all_deps:
                    direction = " <- " if dep['direction'] == 'upstream' else " -> "
                    context_text += f"{dep['related_resource']} {direction} {entity_name} ({dep['relationship']})\n"
                context_docs.append(context_text)
        elif "上游" in query:
            # 获取上游依赖
            upstream_deps = self.dependency_analyzer.find_upstream_dependencies(resource.id)
            if upstream_deps:
                context_text = f"{entity_name}的上游依赖:\n"
                for dep in upstream_deps:
                    context_text += f"- {dep['name']} ({dep['relationship']})\n"
                context_docs.append(context_text)
        elif "下游" in query:
            # 获取下游依赖
            downstream_deps = self.dependency_analyzer.find_downstream_dependencies(resource.id)
            if downstream_deps:
                context_text = f"{entity_name}的下游依赖:\n"
                for dep in downstream_deps:
                    context_text += f"- {dep['name']} ({dep['relationship']})\n"
                context_docs.append(context_text)
        elif "依赖" in query:
            # 获取所有依赖
            all_deps = self.dependency_analyzer.find_all_dependencies(resource.id)
            if all_deps:
                context_text = f"{entity_name}的所有依赖关系:\n"
                for dep in all_deps:
                    direction = " <- " if dep['direction'] == 'upstream' else " -> "
                    context_text += f"{dep['related_resource']} {direction} {entity_name} ({dep['relationship']})\n"
                context_docs.append(context_text)
        
        return context_docs
    
    def _build_containment_context(self) -> List[str]:
        """构建包含关系查询的上下文"""
        # 查找所有包含关系
        containment_relationships = self.db.query(RelationshipDefinition).filter(
            RelationshipDefinition.name.like('%包含%')
        ).all()
        
        if not containment_relationships:
            return []
        
        # 获取包含关系的ID
        containment_ids = [rel.id for rel in containment_relationships]
        
        # 查找所有包含关系的实例
        containment_instances = self.db.query(ResourceEntitiesMap).filter(
            ResourceEntitiesMap.relation_id.in_(containment_ids)
        ).all()
        
        if not containment_instances:
            return []
        
        context_docs = []
        context_text = "包含关系资源:\n"
        
        for instance in containment_instances:
            # 获取起始节点和结束节点
            start_node = self.db.query(ResourceDetails).filter_by(id=instance.start_nodes_id).first()
            end_node = self.db.query(ResourceDetails).filter_by(id=instance.end_nodes_id).first()
            
            if start_node and end_node:
                # 获取关系定义
                relationship_def = self.db.query(RelationshipDefinition).filter_by(id=instance.relation_id).first()
                relationship_name = relationship_def.name if relationship_def else '包含'
                
                context_text += f"- {start_node.details_name} --({relationship_name})--> {end_node.details_name}\n"
        
        context_docs.append(context_text)
        return context_docs
    
    def _build_resource_by_id_context(self, resource_id: str) -> List[str]:
        """根据资源ID构建资源详情上下文"""
        # 直接从数据库获取资源详情
        resource = self.db.query(ResourceDetails).filter_by(id=resource_id).first()
        
        if not resource:
            return [f"未找到ID为 {resource_id} 的资源"]
        
        # 获取资源类别信息
        category = self.db.query(ResourceCategory).filter_by(id=resource.category_id).first()
        
        # 构建资源详情文本
        resource_details = f"资源ID: {resource.id}\n"
        resource_details += f"资源名称: {resource.details_name}\n"
        resource_details += f"资源类别: {category.category_name if category else '未知'}\n"
        resource_details += f"描述: {resource.description or '无描述'}\n"
        resource_details += f"主机: {resource.host or '未指定'}\n"
        resource_details += f"创建时间: {resource.create_time or '未知'}\n"
        resource_details += f"更新时间: {resource.update_time or '未知'}\n"
        
        # 添加注解信息（如果存在）
        if resource.annotations:
            resource_details += f"注解: {resource.annotations}\n"
        
        return [resource_details]